﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyEngineExercise.我的扩展.自定义接口;
using ESRI.ArcGIS.SystemUI;
using System.Runtime.InteropServices;
using MyEngineExercise.我的扩展.自定义事件参数类;
using ESRI.ArcGIS.Display;
using System.Drawing;
using System.Windows.Forms;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;

namespace MyEngineExercise.我的扩展.绘制几何图形
{
    /// <summary>
    /// 绘制多边形工具
    /// </summary>
    public class PolygonFeedbackTool:IGeometryComplete,ITool,ICommand
    {
        [DllImport("gdi32.dll")]
        static extern bool DeleteObject(IntPtr hObject);


        /// <summary>
        /// 事件：几何图形绘制完成后发生
        /// </summary>
        public event EventHandler<GeometryCompleteArgs> GeometryComplete = null;

        private Bitmap _bitmap = null;//工具栏图标
        private IntPtr _hBitmap = IntPtr.Zero;
        private Cursor _crossCursor = null;
        private Cursor _panCursor = null;

        private IHookHelper _hookHelper = null;
        private IHookActions _hookActions = null;

        private INewPolygonFeedback _newPolygonFeedback = null;

        private Boolean _isMouseDown = false;//记录是否有点击鼠标左键
        private Boolean _isPanUsed = false;//是否在使用pan
        private Boolean _isMouseDownFirstClick = false;//画多边形操作，是否第一次点击鼠标左键,标记在mousemove的时候是是否更新最后一个点数据


        /// <summary>
        /// 记录当前ScreenDisplay实例,用于pan操作
        /// </summary>
        private IScreenDisplay _focusScreenDisplay = null;


        private const Int32 CLICK_LEFT_MOUSE = 1;
        private const Int32 RIGHT_MOUSE = 2;
        private const Int32 CLICK_MIDDLE_MOUSE = 4;
        private const Int32 NONE_MOUSE = 0;


        /// <summary>
        /// 用于主窗口状态栏显示面积
        /// </summary>
        private ToolStripStatusLabel _toolStripStatusLabel = null;


        /// <summary>
        /// 保存生成的IPolygon
        /// </summary>
        private IPolygon _polygon = null;


        /// <summary>
        /// 保存第一个点坐标实例
        /// </summary>
        private IPoint _point = null;


        /// <summary>
        /// 记录点坐标
        /// </summary>
        private IPointCollection4 _pointCollection = null;


        /// <summary>
        /// 构造函数
        /// </summary>
        public PolygonFeedbackTool(ToolStripStatusLabel toolStripStatusLabel)
        {
            _toolStripStatusLabel = toolStripStatusLabel;

            _hookHelper = new HookHelperClass();

            _crossCursor = CursorStyle.GetCursor(Constants.CROSS_CURSOR_FILENAME);
            _panCursor = CursorStyle.GetCursor(Constants.MOVEHAND_CURSOR_FILENAME);


            if (_crossCursor == null)
                MessageBox.Show("cross cursor is null");
            if (_panCursor == null)
                MessageBox.Show("pan cursor is null");


            _bitmap = MyEngineExercise.Properties.Resources.drawPolygonIcon;
            _hBitmap = _bitmap.GetHbitmap();
        }


        /// <summary>
        /// 析构函数
        /// </summary>
        ~PolygonFeedbackTool()
        {
            if (_hBitmap.ToInt32() != 0)
                DeleteObject(_hBitmap);

            _hookHelper = null;
            _crossCursor = null;
            _panCursor = null;
        }



        #region 实现ICommand

        public int Bitmap { get { return _hBitmap.ToInt32(); } }

        public string Caption { get { return "Caption"; } }

        public string Category { get { return "GiftGis_FeedBackTools"; } }

        public bool Checked { get { return false; } }

        //public bool Enabled { get { return _hookHelper.ActiveView is Map; } }
        public bool Enabled { get { return true; } }

        public int HelpContextID { get { return 0; } }

        public string HelpFile { get { return null; } }

        public string Message { get { return "画多边形"; } }

        public string Name { get { return "Name"; } }

        public string Tooltip { get { return "画多边形"; } }

        public void OnClick() { }

        public void OnCreate(object hook)
        {
            _hookHelper.Hook = hook;
            _hookActions = (IHookActions)_hookHelper;
        }

        #endregion



        #region 实现ITool

        public int Cursor { get { return (_isPanUsed ? _panCursor : _crossCursor).Handle.ToInt32(); } }


        public bool Deactivate() { return true; }


        public bool OnContextMenu(int x, int y) { return false; }


        public void OnDblClick()
        {
        }


        public void OnKeyDown(int keyCode, int shift)
        {
            if (_isMouseDown && keyCode == 27) // ESC
            {
                _isMouseDown = false;
                _isMouseDownFirstClick = false;
                _newPolygonFeedback = null;
                _polygon = null;
                _pointCollection = null;

                _hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
            }
        }


        public void OnKeyUp(int keyCode, int shift) { }


        public void OnMouseDown(int button, int shift, int x, int y)
        {
            IActiveView activeView = _hookHelper.ActiveView;

            if (null == activeView)
                return;

            //如果活动视图是page，设置page的focusmap是点所在map
            //If the active view is a page layout
            if (activeView is IPageLayout)
            {
                //Create a point in map coordinates
                IPoint point = (IPoint)activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
                //Get the map if the point is within a data frame
                IMap map = activeView.HitTestMap(point);
                if (null == map)
                    return;

                //Set the map to be the page layout's focus map
                if (_hookHelper.FocusMap != map)
                {
                    activeView.FocusMap = map;
                    activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
                }
               
            }

            //Create a point in map coordinates
            activeView = (IActiveView)_hookHelper.FocusMap;
            _point = activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);

            if (button == CLICK_MIDDLE_MOUSE)//中键，pan操作
            {
                _focusScreenDisplay = getFocusScreenDisplay();
                _focusScreenDisplay.PanStart(_point);
                _isPanUsed = true;//标记为进行pan操作
            }
            else if (button == CLICK_LEFT_MOUSE)//左键，画polygon操作
            {
                if (_isMouseDown == false)//如果是第一次单击
                {
                    _newPolygonFeedback = new NewPolygonFeedbackClass();

                    #region 设置样式
                    //设置颜色
                    IRgbColor rgbColor = new RgbColorClass();
                    rgbColor.Red = 120;
                    rgbColor.Green = 150;
                    rgbColor.Blue = 250;

                    // 设置线样式
                    ISimpleLineSymbol simpleLineSymbol = (ISimpleLineSymbol)_newPolygonFeedback.Symbol;
                    simpleLineSymbol.Color = rgbColor;
                    simpleLineSymbol.Style = esriSimpleLineStyle.esriSLSDot;
                    simpleLineSymbol.Width = 1.4;
                    #endregion

                    _polygon = new PolygonClass();
                    _pointCollection = (IPointCollection4)_polygon;

                    Object missing = Type.Missing;
                    //为什么添加2次？因为后面要更新最后一个点，最后一个点的坐标是什么都无所谓
                    _pointCollection.AddPoint(_point, ref missing, ref missing);
                    _pointCollection.AddPoint(_point, ref missing, ref missing);
                }
            }
        }


        public void OnMouseMove(int button, int shift, int x, int y)
        {
        }


        public void OnMouseUp(int button, int shift, int x, int y)
        {
        }


        public void Refresh(int hdc)
        {
            // 注意，必须设置这里，否则，当地图放大缩小后线就会移动。
            if (null != _newPolygonFeedback)
                _newPolygonFeedback.Refresh(hdc);
        }


        #endregion


        /// <summary>
        /// 获取IScreenDisplay，map和page方法不同
        /// </summary>
        /// <returns></returns>
        private IScreenDisplay getFocusScreenDisplay()
        {
            //Get the ScreenDisplay that has focus
            IActiveView activeView = _hookHelper.ActiveView;

            if (activeView is IMap)
                return activeView.ScreenDisplay;
            else
            {
                activeView = (IActiveView)activeView.FocusMap;
                return activeView.ScreenDisplay;
            }
        }

    }
}
